package math2;

import fem2.BasisManager;
import fem2.MeshPart;
import fem2.Node;

public class IsoparametricBlockGeometry extends IsoparametricGeometry {

	private static IsoparametricBlockGeometry instance = new IsoparametricBlockGeometry();

	private IsoparametricBlockGeometry() {
	}

	/**
	 * Get the instance of IsoparametricEdgeGeometry singleton
	 * 
	 * @return the Singleton instance
	 */
	public static IsoparametricBlockGeometry getInstance() {
		return instance;
	}

	@Override
	public double[][] jacobianAt(MeshPart mp, double... xi) {
		Node[] nodes = mp.getNodes();
		FunctionBasisOnRnToR basis = BasisManager.getInstance().getBasis(mp.getType());
		double j11 = 0, j12 = 0, j13 = 0;
		double j21 = 0, j22 = 0, j23 = 0;
		double j31 = 0, j32 = 0, j33 = 0;
		for (int i = 0; i < nodes.length; i++) {
			FunctionRnToR Ni = basis.getBasisFunction(i);
			double[] dNi = Ni.gradientAt(xi);
			double[] X = nodes[i].getPosition();
			j11 += dNi[0] * X[0];
			j12 += dNi[0] * X[1];
			j13 += dNi[0] * X[2];
			j21 += dNi[1] * X[0];
			j22 += dNi[1] * X[1];
			j23 += dNi[1] * X[2];
			j31 += dNi[2] * X[0];
			j32 += dNi[2] * X[1];
			j33 += dNi[2] * X[2];
		}
		return new double[][] { { j11, j12, j13 }, { j21, j22, j23 }, { j31, j32, j33 } };
	}
}
